package run.fenglu.jls.controller;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import run.fenglu.jls.util.JrebelSign;
import run.fenglu.jls.util.Rsasign;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class JrebelLSController {

    @Value("${jrebel.constant.signature}")
    private String signature;
    @Value("${jrebel.constant.serverVersion}")
    private String serverVersion;
    @Value("${jrebel.constant.serverProtocolVersion}")
    private String serverProtocolVersion;
    @Value("${jrebel.constant.groupType}")
    private String groupType;

    @RequestMapping(value = {"/jrebel/leases", "/agent/leases", "/{uuid}/jrebel/leases", "/{uuid}/agent/leases"})
    public Map<String, Object> leases(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> ret = new HashMap<>();
        String clientRandomness = request.getParameter("randomness");
        String username = request.getParameter("username");
        String guid = request.getParameter("guid");
        boolean offline = Boolean.parseBoolean(request.getParameter("offline"));
        long validFrom = System.currentTimeMillis();
        long validUntil = 0;
        if (offline) {
            String clientTime = request.getParameter("clientTime");
            String offlineDays = request.getParameter("offlineDays");
            //long clinetTimeUntil = Long.parseLong(clientTime) + Long.parseLong(offlineDays)  * 24 * 60 * 60 * 1000;
            long clinetTimeUntil = Long.parseLong(clientTime) + 180L * 24 * 60 * 60 * 1000;
            validFrom = Long.parseLong(clientTime);
            validUntil = clinetTimeUntil;
            ret.put("validFrom", validFrom);
            ret.put("validUntil", validUntil);
        }
        ret.put("serverVersion", serverVersion);
        ret.put("serverProtocolVersion", serverProtocolVersion);
        ret.put("serverGuid", UUID.randomUUID());
        ret.put("groupType", groupType);
        ret.put("id", 1);
        ret.put("licenseType", 1);
        ret.put("evaluationLicense", false);
        ret.put("signature", signature);
        String serverRandomness = RandomStringUtils.randomAlphanumeric(12);
        ret.put("serverRandomness", serverRandomness);
        ret.put("seatPoolType", "standalone");
        ret.put("statusCode", "SUCCESS");
        ret.put("offline", offline);
        ret.put("orderId", "");
        ret.put("zeroIds", Arrays.asList());
        ret.put("licenseValidFrom", validFrom);
        ret.put("licenseValidUntil", validFrom + 3L * 365 * 24 * 60 * 60 * 1000);

        if (clientRandomness == null || username == null || guid == null) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return null;
        } else {
            JrebelSign jrebelSign = new JrebelSign();
            jrebelSign.toLeaseCreateJson(clientRandomness, serverRandomness, guid, offline, String.valueOf(validFrom), String.valueOf(validUntil));
            String signature = jrebelSign.getSignature();
            ret.put("signature", signature);
            ret.put("company", username);
            return ret;
        }
    }

    @RequestMapping(value = {"/jrebel/leases/1", "/agent/leases/1"})
    public Map<String, Object> leases1(HttpServletRequest request) {
        Map<String, Object> ret = new HashMap<>();
        String username = request.getParameter("username");
        ret.put("serverVersion", serverVersion);
        ret.put("serverProtocolVersion", serverProtocolVersion);
        ret.put("serverGuid", UUID.randomUUID());
        ret.put("groupType", groupType);
        ret.put("statusCode", "SUCCESS");
        ret.put("msg", null);
        ret.put("statusMessage", null);
        if (username != null) {
            ret.put("company", username);
        }
        return ret;
    }

    @RequestMapping("/jrebel/validate-connection")
    public Map<String, Object> jrebelVc() {
        Map<String, Object> ret = new HashMap<>();
        ret.put("serverVersion", serverVersion);
        ret.put("serverProtocolVersion", serverProtocolVersion);
        ret.put("serverGuid", UUID.randomUUID());
        ret.put("groupType", groupType);
        ret.put("statusCode", "SUCCESS");
        ret.put("company", "NFL");
        ret.put("canGetLease", true);
        ret.put("licenseType", 1);
        ret.put("evaluationLicense", false);
        ret.put("seatPoolType", "standalone");
        return ret;
    }

    @RequestMapping("/rpc/ping.action")
    public String ping(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        String salt = request.getParameter("salt");
        if (salt == null) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return null;
        } else {
            String xmlContent = "<PingResponse><message></message><responseCode>OK</responseCode><salt>" + salt + "</salt></PingResponse>";
            String xmlSignature = Rsasign.Sign(xmlContent);
            String body = "<!-- " + xmlSignature + " -->\n" + xmlContent;
            return body;
        }
    }

    @RequestMapping("/rpc/obtainTicket.action")
    public String obtainTicket(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        SimpleDateFormat fm = new SimpleDateFormat("EEE,d MMM yyyy hh:mm:ss Z", Locale.ENGLISH);
        String date = fm.format(new Date()) + " GMT";
        //response.setHeader("Date", date);
        //response.setHeader("Server", "fasthttp");
        String salt = request.getParameter("salt");
        String username = request.getParameter("userName");
        String prolongationPeriod = "607875500";
        if (salt == null || username == null) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return null;
        } else {
            String xmlContent = "<ObtainTicketResponse><message></message><prolongationPeriod>" + prolongationPeriod + "</prolongationPeriod><responseCode>OK</responseCode><salt>" + salt + "</salt><ticketId>1</ticketId><ticketProperties>licensee=" + username + "\tlicenseType=0\t</ticketProperties></ObtainTicketResponse>";
            String xmlSignature = Rsasign.Sign(xmlContent);
            String body = "<!-- " + xmlSignature + " -->\n" + xmlContent;
            return body;
        }
    }

    @RequestMapping("/rpc/releaseTicket.action")
    public String releaseTicket(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        String salt = request.getParameter("salt");
        if (salt == null) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return null;
        } else {
            String xmlContent = "<ReleaseTicketResponse><message></message><responseCode>OK</responseCode><salt>" + salt + "</salt></ReleaseTicketResponse>";
            String xmlSignature = Rsasign.Sign(xmlContent);
            String body = "<!-- " + xmlSignature + " -->\n" + xmlContent;
            return body;
        }
    }

    private Map<String, Object> initRet() {
        return null;
    }
}
